1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use super::*;
#[derive(Clone, Eq, PartialEq, Default)]
pub struct SymbolSet(Option<HashMap<SymbolId, Dependency>>);
impl SymbolSet {
pub const EMPTY: SymbolSet = SymbolSet(None);
pub fn singleton(symbol: SymbolId, dependency: Dependency) -> SymbolSet {
let mut set = HashMap::default();
set.insert(symbol, dependency);
SymbolSet(Some(set))
}
pub fn insert(&mut self, symbol: SymbolId, dependency: Dependency) -> bool {
let dependency = dependency.of(&symbol);
if let Some(set) = self.0.as_mut() {
match set.entry(symbol) {
Entry::Vacant(v) => {
v.insert(dependency);
true
}
Entry::Occupied(mut o) => {
let join = o.get().join(dependency);
let old = o.insert(dependency);
join != old
}
}
} else {
*self = SymbolSet::singleton(symbol, dependency);
true
}
}
pub fn insert_set(&mut self, symbols: &SymbolSet) {
if let Some(symbols) = &symbols.0 {
for (symbol, &dependency) in symbols.iter() {
self.insert(symbol.clone(), dependency);
}
}
}
pub fn remove(&mut self, symbol: &SymbolId) -> Option<Dependency> {
if let Some(set) = self.0.as_mut() {
let change = set.remove(symbol);
if set.is_empty() {
*self = SymbolSet(None)
}
change
} else {
None
}
}
pub fn get(&self, symbol: &SymbolId) -> Option<Dependency> {
if let Some(set) = self.0.as_ref() {
set.get(symbol).copied()
} else {
None
}
}
pub fn contains(&self, symbol: &SymbolId) -> bool {
self.get(symbol).is_some()
}
pub fn union(&self, other: &SymbolSet) -> SymbolSet {
if self.len() < other.len() {
return other.union(self);
}
let mut result = self.clone();
for (symbol, &dependency) in other.iter() {
result.insert(symbol.clone(), dependency);
}
result
}
pub fn is_empty(&self) -> bool {
self.0.as_ref().map(|set| set.is_empty()).unwrap_or(true)
}
pub fn len(&self) -> usize {
if let Some(set) = &self.0 {
set.len()
} else {
0
}
}
pub fn borrow_deps(&mut self) {
for (_, dependency) in self.iter_mut() {
*dependency = dependency.meet(dependency.flip());
dependency.relationship = dependency.relationship.meet_usage(Usage::UNUSED);
}
}
pub fn borrowed_deps(&self) -> SymbolSet {
let mut result = self.clone();
result.borrow_deps();
result
}
pub fn iter(&self) -> impl Iterator<Item = (&SymbolId, &Dependency)> {
self.0.iter().flat_map(|set| set.iter())
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&SymbolId, &mut Dependency)> {
self.0.iter_mut().flat_map(|set| set.iter_mut())
}
}
impl Debug for SymbolSet {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
if let Some(set) = &self.0 {
Debug::fmt(set, fmt)
} else {
write!(fmt, "{{}}")
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn symbol_dep_partial_ord() {
for dep in Dependency::iter_all() {
assert!(
Dependency::CONTRADICTION <= dep,
"{:?} <= {:?}",
Dependency::CONTRADICTION,
dep
);
}
}
}